While the BizTalk WCF Service Publishing Wizard produces a fairly clean WSDL file, we are clearly establishing more structural control by building these contracts by hand.
The next step is to switch to the BizTalk Administration Console and create a new one-way receive port/receive location combo. I've chosen the WCF-Custom adapter for the receive location which means that the in-process, BizTalkServerApplication host is used.
Now we need to configure this custom endpoint. Skip ahead to the Binding tab within the WCF-Custom Transport Properties window. I've decided that this custom WCF adapter will exploit the basicHTTP binding.
Now, we can switch back to the General tab and assign an HTTP address for this endpoint. I've chosen an arbitrary port number and URI (http://localhost:4044/SiteRegistrationService/service.svc
) to represent this endpoint.
Finally, let's add a new behavior to this endpoint so that service clients can interrogate the WSDL. On the Behavior tab, we right-click the Service Behavior node and choose to Add Extension. In the Select Behavior Extension window, we should choose the serviceMetadata entry. Then, we must be sure to flip the serviceMetadata httpGetEnabled to True. If you recall from our WCF discussion earlier, we use this behavior to explicitly turn metadata retrieval on and off. property named
If we enable this receive location, and browse to the chosen URL, we'll
be presented with the standard WCF service description page.
However, if we look at the available WSDL, we'll notice a generic BizTalkSubmit
operation and no explicit schema. This makes sense because our receive
location has absolutely no idea what type of data we plan on passing to
it. Let's help it out, shall we? Go back to the receive location we
created, open the adapter configuration window, switch to the Behavior tab and choose the serviceMetadata behavior listed there. This behavior has a property named externalMetadataLocation
where we can specify which outside WSDL file should be a substitute for
whatever the receive location would have generated on its own. I
populated this property with the URL of my hand-built WSDL.
Pitfall
The
WSDL file must be accessed through an HTTP or HTTPS channel by the
adapter. If you try and point to a WSDL using a file system URI, the
receive location will fail to start and throws an error. You can
resolve this by placing the WSDL in an IIS web directory and
referencing it there.
Now if I browse this service again, I see that the custom WSDL file is served up instead of the auto-generated one.
Notice
that I could also use this pattern to accept "generic" content into my
receive location and avoid the throwaway orchestration demonstrated in
the previous section. Our custom-built WSDL could designate an
arbitrary payload for our service operation.
This
pattern demonstrates a clean way to attach "type" details to a WCF
receive location in a very loosely-coupled way. Note however, that
there is no practical reason to avoid hosting our services in IIS 7.0
and choosing the in-process hosting instead. The best part is, an
endpoint hosted in IIS can still take advantage of the externalMetadataLocation
property set in the corresponding receive location. Hence, this little
trick isn't just for in-process hosting but rather, available to any
WCF adapter in any hosting environment.
Consider
using the "custom" WCF adapters in all situations. In doing so, you get
easy access to binding configurations and behaviors that are
inaccessible from the transport-specific WCF adapters. Also, if you
need to upgrade the capabilities of the port in the future, there is no
need to create new ports and rebind existing processes.